package cn.boodqian.airdata;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.logging.Logger;

import javax.servlet.ServletContext;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;

public abstract class AirDataProvider {
	public abstract Date getAirData(Key parent, int hours);
	public abstract String getLastError();
	public abstract String getCity();
	
	private final static Logger Log = Logger.getLogger("AirDataProvider");
	public final static String kind = "AirData2";
	protected ServletContext mServeletContext = null;
	
	public AirDataProvider(ServletContext context) {
		mServeletContext = context;
	}
	
	public static ArrayList<HashMap<String, String>> initLoationList(String[][] locationRawList, String idCity, String displayCity) {
		
		ArrayList<HashMap<String, String>> locationList = new ArrayList<HashMap<String,String>>();
		
		// Chinese begin
		for(String[] location : locationRawList) {
			assert( location.length >= 3 );
			
			HashMap<String, String> map = new HashMap<String, String>();
			map.put("id", idCity+"/"+location[0]);
			map.put("address", location[1]);
			map.put("name", location[2]);
			if(location.length>=4) map.put("tip", location[3]);
			else  map.put("tip", "");
			map.put("city", displayCity);
			
			locationList.add(map);
		}
		
		return locationList;
	}
	
	protected void doFetch(int hours)
	{
		DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
		
		// Check latest data to see if an update needs to be scheduled
		// Note LastUpdate means last successful update for ALL locations
		Date now = new Date();
		Key parent = KeyFactory.createKey(kind, getCity());
		Key updateKey = KeyFactory.createKey(parent, "LastUpdate", "LastUpdate");
		Entity lastUpdate = null;
		try {
			lastUpdate = datastore.get(updateKey);
		} catch (EntityNotFoundException e) {
		}
		if(lastUpdate == null) {
			Log.info("No last update time found");
			lastUpdate = new Entity(updateKey);
		} else {
			Date time = (Date) lastUpdate.getProperty("time");
			Log.info("Last update of " + getCity() + ":" + Global.FmtUTC8.format(time));
			if( now.getTime() - time.getTime() < 80*60*1000 ) { // At least wait 1 hour 20 minutes
				Log.info("Not a good time to update " + getCity());
				return;
			}
		}
		
		// Call worker function to update data
		// Will return success update date if all location is updated successfully
		Date thisUpdateDate = getAirData(parent, hours);
		
		if( thisUpdateDate != null ) {
			Log.info("Update last update time to " + Global.FmtUTC8.format(thisUpdateDate));
			lastUpdate.setUnindexedProperty("time", thisUpdateDate);
			datastore.put(lastUpdate);
		}
	}
}
